package codec

import (
	"gitee.com/yanwc/ebike-xiaoan-device/internal/field"
	"gitee.com/yanwc/ebike-xiaoan-device/internal/frame"
	"gitee.com/yanwc/net/utils"
	"github.com/panjf2000/gnet"
	gerrors "github.com/panjf2000/gnet/pkg/errors"
)

type BikeFrameCodec struct{}

var _ gnet.ICodec = (*BikeFrameCodec)(nil)

func (cc *BikeFrameCodec) Decode(c gnet.Conn) (b []byte, err error) {
	buf := c.Read()
	idx := magic.IndexOf(buf)
	if idx < 0 {
		return nil, gerrors.ErrIncompletePacket
	}

	var magic frame.MagicRaw
	var cmdWord field.CommandWordRaw
	var sn field.SerialNumberRaw
	var l ContentLengthRaw

	startIndex := idx + len(magic)
	endIndex := startIndex + len(cmdWord) + len(sn) + len(l)
	if endIndex > len(buf) {
		return nil, gerrors.ErrIncompletePacket
	}

	err = utils.LoadPacket(buf[startIndex:endIndex], cmdWord[:], sn[:], l[:])
	endIndex = endIndex + int(l.Type())
	if endIndex > len(buf) {
		return nil, gerrors.ErrIncompletePacket
	}

	b = make([]byte, endIndex-startIndex)
	copy(b, buf[startIndex:endIndex])
	c.ShiftN(endIndex)
	return
}

func (cc *BikeFrameCodec) Encode(c gnet.Conn, buf []byte) (out []byte, err error) {
	out = append(out, utils.NumberToBytesWithBigEndian(magic)...)
	out = append(out, buf...)
	return
}
